<template>
  <div class="min-h-screen py-8 px-4 sm:px-6 lg:px-8">
    <div class="max-w-6xl mx-auto">
      <!-- 页面标题 -->
      <div class="text-center mb-12">
        <h1 class="text-4xl font-bold mb-4 tech-text">MediaStream Image Capture API</h1>
        <p class="text-gray-300 text-lg">
          从摄像头捕获高质量图片，控制相机参数和获取设备能力
        </p>
      </div>

      <!-- 浏览器支持提示 -->
      <div v-if="!isSupported" class="tech-card mb-8 border-yellow-600">
        <div class="flex items-center mb-4">
          <i class="i-carbon-warning text-yellow-500 text-xl mr-3"></i>
          <h3 class="text-xl font-semibold text-yellow-500">浏览器支持提示</h3>
        </div>
        <p class="text-gray-300 mb-4">
          您的浏览器不支持 ImageCapture API。此功能需要 Chrome 59+, Edge 79+ 或其他支持该 API 的浏览器。
        </p>
      </div>

      <!-- 摄像头控制 -->
      <div class="tech-card mb-8">
        <h2 class="text-2xl font-semibold mb-6 text-white">摄像头控制</h2>
        
        <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
          <!-- 视频预览 -->
          <div>
            <div class="bg-gray-800 rounded-lg overflow-hidden mb-4">
              <video
                ref="videoRef"
                autoplay
                playsinline
                class="w-full h-auto"
                :class="!stream ? 'hidden' : ''"
              ></video>
              <div
                v-if="!stream"
                class="w-full h-64 flex flex-col items-center justify-center text-gray-400"
              >
                <i class="i-carbon-video text-6xl mb-4"></i>
                <p>点击下方按钮启动摄像头</p>
              </div>
            </div>

            <div class="flex gap-3">
              <button
                v-if="!stream"
                @click="startCamera"
                :disabled="!isSupported"
                class="tech-button flex-1 disabled:opacity-50 disabled:cursor-not-allowed"
              >
                <i class="i-carbon-video mr-2"></i>
                启动摄像头
              </button>
              <button
                v-else
                @click="stopCamera"
                class="bg-red-600 hover:bg-red-700 text-white px-6 py-3 rounded-lg transition-colors flex-1"
              >
                <i class="i-carbon-video-off mr-2"></i>
                停止摄像头
              </button>
              
              <button
                v-if="stream"
                @click="capturePhoto"
                class="tech-button flex-1"
              >
                <i class="i-carbon-camera mr-2"></i>
                拍照
              </button>
            </div>
          </div>

          <!-- 相机信息 -->
          <div>
            <h3 class="text-lg font-semibold text-white mb-4">相机信息</h3>
            
            <div v-if="!capabilities" class="bg-gray-800 rounded-lg p-6 text-center text-gray-400">
              <i class="i-carbon-information text-3xl mb-2"></i>
              <p>启动摄像头后查看设备能力</p>
            </div>

            <div v-else class="space-y-4">
              <!-- 支持的功能 -->
              <div class="bg-gray-800 rounded-lg p-4">
                <h4 class="text-white font-medium mb-3 flex items-center">
                  <i class="i-carbon-checkmark-filled text-green-400 mr-2"></i>
                  支持的功能
                </h4>
                <div class="grid grid-cols-2 gap-2 text-sm">
                  <div
                    v-for="feature in supportedFeatures"
                    :key="feature.name"
                    class="flex items-center text-gray-300"
                  >
                    <i
                      :class="feature.supported ? 'i-carbon-checkmark text-green-400' : 'i-carbon-close text-red-400'"
                      class="mr-2"
                    ></i>
                    {{ feature.name }}
                  </div>
                </div>
              </div>

              <!-- 分辨率信息 -->
              <div class="bg-gray-800 rounded-lg p-4">
                <h4 class="text-white font-medium mb-3">分辨率范围</h4>
                <div class="space-y-2 text-sm text-gray-300">
                  <div v-if="capabilities.imageWidth">
                    <span class="text-gray-400">宽度:</span>
                    {{ capabilities.imageWidth.min }} - {{ capabilities.imageWidth.max }} px
                  </div>
                  <div v-if="capabilities.imageHeight">
                    <span class="text-gray-400">高度:</span>
                    {{ capabilities.imageHeight.min }} - {{ capabilities.imageHeight.max }} px
                  </div>
                </div>
              </div>

              <!-- 其他参数 -->
              <div class="bg-gray-800 rounded-lg p-4">
                <h4 class="text-white font-medium mb-3">其他参数</h4>
                <div class="space-y-2 text-sm text-gray-300">
                  <div v-if="capabilities.zoom">
                    <span class="text-gray-400">变焦:</span>
                    {{ capabilities.zoom.min }}x - {{ capabilities.zoom.max }}x
                  </div>
                  <div v-if="capabilities.focusDistance">
                    <span class="text-gray-400">对焦距离:</span>
                    {{ capabilities.focusDistance.min }} - {{ capabilities.focusDistance.max }}
                  </div>
                  <div v-if="capabilities.exposureCompensation">
                    <span class="text-gray-400">曝光补偿:</span>
                    {{ capabilities.exposureCompensation.min }} - {{ capabilities.exposureCompensation.max }}
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 相机设置 -->
      <div v-if="stream && capabilities" class="tech-card mb-8">
        <h2 class="text-2xl font-semibold mb-6 text-white">相机设置</h2>
        
        <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
          <!-- 变焦控制 -->
          <div v-if="capabilities.zoom" class="bg-gray-800 rounded-lg p-4">
            <label class="text-white font-medium mb-3 block">
              变焦 ({{ currentSettings.zoom?.toFixed(1) }}x)
            </label>
            <input
              v-model.number="zoomValue"
              type="range"
              :min="capabilities.zoom.min"
              :max="capabilities.zoom.max"
              :step="capabilities.zoom.step || 0.1"
              @input="updateZoom"
              class="w-full"
            >
            <div class="flex justify-between text-xs text-gray-400 mt-1">
              <span>{{ capabilities.zoom.min }}x</span>
              <span>{{ capabilities.zoom.max }}x</span>
            </div>
          </div>

          <!-- 曝光补偿 -->
          <div v-if="capabilities.exposureCompensation" class="bg-gray-800 rounded-lg p-4">
            <label class="text-white font-medium mb-3 block">
              曝光补偿 ({{ currentSettings.exposureCompensation?.toFixed(1) }})
            </label>
            <input
              v-model.number="exposureValue"
              type="range"
              :min="capabilities.exposureCompensation.min"
              :max="capabilities.exposureCompensation.max"
              :step="capabilities.exposureCompensation.step || 0.1"
              @input="updateExposure"
              class="w-full"
            >
            <div class="flex justify-between text-xs text-gray-400 mt-1">
              <span>{{ capabilities.exposureCompensation.min }}</span>
              <span>{{ capabilities.exposureCompensation.max }}</span>
            </div>
          </div>

          <!-- 白平衡模式 -->
          <div v-if="capabilities.whiteBalanceMode && capabilities.whiteBalanceMode.length > 0" class="bg-gray-800 rounded-lg p-4">
            <label class="text-white font-medium mb-3 block">白平衡模式</label>
            <select
              v-model="whiteBalanceMode"
              @change="updateWhiteBalance"
              class="w-full bg-gray-700 text-white px-3 py-2 rounded"
            >
              <option
                v-for="mode in capabilities.whiteBalanceMode"
                :key="mode"
                :value="mode"
              >
                {{ mode }}
              </option>
            </select>
          </div>

          <!-- 对焦模式 -->
          <div v-if="capabilities.focusMode && capabilities.focusMode.length > 0" class="bg-gray-800 rounded-lg p-4">
            <label class="text-white font-medium mb-3 block">对焦模式</label>
            <select
              v-model="focusMode"
              @change="updateFocusMode"
              class="w-full bg-gray-700 text-white px-3 py-2 rounded"
            >
              <option
                v-for="mode in capabilities.focusMode"
                :key="mode"
                :value="mode"
              >
                {{ mode }}
              </option>
            </select>
          </div>
        </div>
      </div>

      <!-- 拍摄的照片 -->
      <div v-if="capturedPhotos.length > 0" class="tech-card mb-8">
        <div class="flex justify-between items-center mb-6">
          <h2 class="text-2xl font-semibold text-white">拍摄的照片 ({{ capturedPhotos.length }})</h2>
          <button
            @click="clearPhotos"
            class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg transition-colors text-sm"
          >
            <i class="i-carbon-trash-can mr-1"></i>
            清空所有
          </button>
        </div>

        <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
          <div
            v-for="photo in capturedPhotos"
            :key="photo.id"
            class="bg-gray-800 rounded-lg overflow-hidden group"
          >
            <div class="relative">
              <img
                :src="photo.url"
                :alt="photo.name"
                class="w-full h-48 object-cover"
              >
              <div class="absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-50 transition-opacity flex items-center justify-center">
                <div class="opacity-0 group-hover:opacity-100 transition-opacity flex gap-2">
                  <button
                    @click="viewPhoto(photo)"
                    class="bg-tech-accent hover:bg-tech-accent/80 text-white p-2 rounded-lg"
                    title="查看"
                  >
                    <i class="i-carbon-view text-xl"></i>
                  </button>
                  <button
                    @click="downloadPhoto(photo)"
                    class="bg-green-600 hover:bg-green-700 text-white p-2 rounded-lg"
                    title="下载"
                  >
                    <i class="i-carbon-download text-xl"></i>
                  </button>
                  <button
                    @click="deletePhoto(photo.id)"
                    class="bg-red-600 hover:bg-red-700 text-white p-2 rounded-lg"
                    title="删除"
                  >
                    <i class="i-carbon-trash-can text-xl"></i>
                  </button>
                </div>
              </div>
            </div>
            <div class="p-4">
              <div class="text-white font-medium mb-2">{{ photo.name }}</div>
              <div class="text-gray-400 text-sm space-y-1">
                <div>{{ photo.width }} × {{ photo.height }} px</div>
                <div>{{ formatFileSize(photo.size) }}</div>
                <div>{{ photo.timestamp }}</div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 照片查看模态框 -->
      <div
        v-if="viewingPhoto"
        @click="closePhotoView"
        class="fixed inset-0 bg-black bg-opacity-90 z-50 flex items-center justify-center p-4"
      >
        <div class="relative max-w-5xl w-full">
          <button
            @click="closePhotoView"
            class="absolute top-4 right-4 bg-gray-800 hover:bg-gray-700 text-white p-2 rounded-lg z-10"
          >
            <i class="i-carbon-close text-2xl"></i>
          </button>
          <img
            :src="viewingPhoto.url"
            :alt="viewingPhoto.name"
            class="w-full h-auto rounded-lg"
            @click.stop
          >
          <div class="mt-4 text-center text-white">
            <div class="text-xl font-semibold mb-2">{{ viewingPhoto.name }}</div>
            <div class="text-gray-400">
              {{ viewingPhoto.width }} × {{ viewingPhoto.height }} px
            </div>
          </div>
        </div>
      </div>

      <!-- API 信息 -->
      <div class="tech-card">
        <h3 class="text-xl font-semibold mb-4 text-white">API 信息</h3>
        <div class="space-y-4 text-gray-300">
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">浏览器支持</h4>
            <p>Chrome 59+, Edge 79+, Opera 46+</p>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">主要接口</h4>
            <ul class="list-disc list-inside space-y-1">
              <li><code class="bg-gray-800 px-2 py-1 rounded">ImageCapture</code> - 图像捕获接口</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">takePhoto()</code> - 拍摄高质量照片</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">grabFrame()</code> - 快速抓取帧</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">getPhotoCapabilities()</code> - 获取相机能力</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">getPhotoSettings()</code> - 获取当前设置</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">可控制的参数</h4>
            <ul class="list-disc list-inside space-y-1">
              <li>变焦 (zoom)</li>
              <li>曝光补偿 (exposureCompensation)</li>
              <li>白平衡模式 (whiteBalanceMode)</li>
              <li>对焦模式 (focusMode)</li>
              <li>ISO 感光度 (iso)</li>
              <li>图像分辨率 (imageWidth, imageHeight)</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">使用场景</h4>
            <ul class="list-disc list-inside space-y-1">
              <li>高质量照片拍摄应用</li>
              <li>证件照和文档扫描</li>
              <li>视频会议截图功能</li>
              <li>相机控制和设置应用</li>
              <li>专业摄影 Web 应用</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">与 getUserMedia 的区别</h4>
            <p class="text-sm">
              ImageCapture API 提供了更精细的相机控制和更高质量的图像捕获能力，
              而 getUserMedia 主要用于获取媒体流。ImageCapture 可以访问相机的原生分辨率，
              并提供了诸如变焦、曝光、对焦等高级控制功能。
            </p>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

// 类型定义
interface CapturedPhoto {
  id: string
  name: string
  url: string
  width: number
  height: number
  size: number
  timestamp: string
}

interface SupportedFeature {
  name: string
  supported: boolean
}

// 响应式状态
const isSupported = ref('ImageCapture' in window)
const videoRef = ref<HTMLVideoElement | null>(null)
const stream = ref<MediaStream | null>(null)
const imageCapture = ref<ImageCapture | null>(null)
const capabilities = ref<any>(null)
const currentSettings = ref<any>({})

// 相机设置
const zoomValue = ref(1)
const exposureValue = ref(0)
const whiteBalanceMode = ref('auto')
const focusMode = ref('continuous')

// 照片
const capturedPhotos = ref<CapturedPhoto[]>([])
const viewingPhoto = ref<CapturedPhoto | null>(null)

// 支持的功能
const supportedFeatures = ref<SupportedFeature[]>([])

// 启动摄像头
const startCamera = async () => {
  try {
    const mediaStream = await navigator.mediaDevices.getUserMedia({
      video: {
        width: { ideal: 1920 },
        height: { ideal: 1080 }
      }
    })
    
    stream.value = mediaStream
    
    if (videoRef.value) {
      videoRef.value.srcObject = mediaStream
    }
    
    // 创建 ImageCapture 实例
    const videoTrack = mediaStream.getVideoTracks()[0]
    imageCapture.value = new ImageCapture(videoTrack)
    
    // 获取相机能力
    await loadCapabilities()
    await loadSettings()
    
  } catch (err) {
    console.error('启动摄像头失败:', err)
    alert('无法访问摄像头，请确保已授予权限')
  }
}

// 停止摄像头
const stopCamera = () => {
  if (stream.value) {
    stream.value.getTracks().forEach(track => track.stop())
    stream.value = null
  }
  
  if (videoRef.value) {
    videoRef.value.srcObject = null
  }
  
  imageCapture.value = null
  capabilities.value = null
  currentSettings.value = {}
}

// 加载相机能力
const loadCapabilities = async () => {
  if (!imageCapture.value) return
  
  try {
    const caps = await imageCapture.value.getPhotoCapabilities()
    capabilities.value = caps
    
    // 初始化设置值
    if (caps.zoom) {
      zoomValue.value = caps.zoom.min
    }
    if (caps.exposureCompensation) {
      exposureValue.value = (caps.exposureCompensation.min + caps.exposureCompensation.max) / 2
    }
    
    // 检查支持的功能
    supportedFeatures.value = [
      { name: '变焦', supported: !!caps.zoom },
      { name: '曝光补偿', supported: !!caps.exposureCompensation },
      { name: '白平衡', supported: !!caps.whiteBalanceMode && caps.whiteBalanceMode.length > 0 },
      { name: '对焦模式', supported: !!caps.focusMode && caps.focusMode.length > 0 },
      { name: 'ISO', supported: !!caps.iso },
      { name: '亮度', supported: !!caps.brightness },
      { name: '对比度', supported: !!caps.contrast },
      { name: '饱和度', supported: !!caps.saturation }
    ]
    
  } catch (err) {
    console.error('获取相机能力失败:', err)
  }
}

// 加载当前设置
const loadSettings = async () => {
  if (!imageCapture.value) return
  
  try {
    const settings = await imageCapture.value.getPhotoSettings()
    currentSettings.value = settings
  } catch (err) {
    console.error('获取相机设置失败:', err)
  }
}

// 更新变焦
const updateZoom = async () => {
  if (!stream.value) return
  
  try {
    const videoTrack = stream.value.getVideoTracks()[0]
    await videoTrack.applyConstraints({
      advanced: [{ zoom: zoomValue.value } as any]
    })
    await loadSettings()
  } catch (err) {
    console.error('更新变焦失败:', err)
  }
}

// 更新曝光
const updateExposure = async () => {
  if (!stream.value) return
  
  try {
    const videoTrack = stream.value.getVideoTracks()[0]
    await videoTrack.applyConstraints({
      advanced: [{ exposureCompensation: exposureValue.value } as any]
    })
    await loadSettings()
  } catch (err) {
    console.error('更新曝光失败:', err)
  }
}

// 更新白平衡
const updateWhiteBalance = async () => {
  if (!stream.value) return
  
  try {
    const videoTrack = stream.value.getVideoTracks()[0]
    await videoTrack.applyConstraints({
      advanced: [{ whiteBalanceMode: whiteBalanceMode.value } as any]
    })
    await loadSettings()
  } catch (err) {
    console.error('更新白平衡失败:', err)
  }
}

// 更新对焦模式
const updateFocusMode = async () => {
  if (!stream.value) return
  
  try {
    const videoTrack = stream.value.getVideoTracks()[0]
    await videoTrack.applyConstraints({
      advanced: [{ focusMode: focusMode.value } as any]
    })
    await loadSettings()
  } catch (err) {
    console.error('更新对焦模式失败:', err)
  }
}

// 拍照
const capturePhoto = async () => {
  if (!imageCapture.value) return
  
  try {
    const blob = await imageCapture.value.takePhoto()
    
    // 创建图片对象以获取尺寸
    const img = new Image()
    const url = URL.createObjectURL(blob)
    
    img.onload = () => {
      const photo: CapturedPhoto = {
        id: `photo-${Date.now()}-${Math.random()}`,
        name: `照片_${new Date().toLocaleTimeString('zh-CN')}.jpg`,
        url,
        width: img.width,
        height: img.height,
        size: blob.size,
        timestamp: new Date().toLocaleString('zh-CN')
      }
      
      capturedPhotos.value.unshift(photo)
    }
    
    img.src = url
    
  } catch (err) {
    console.error('拍照失败:', err)
    alert('拍照失败，请重试')
  }
}

// 查看照片
const viewPhoto = (photo: CapturedPhoto) => {
  viewingPhoto.value = photo
}

// 关闭照片查看
const closePhotoView = () => {
  viewingPhoto.value = null
}

// 下载照片
const downloadPhoto = (photo: CapturedPhoto) => {
  const a = document.createElement('a')
  a.href = photo.url
  a.download = photo.name
  a.click()
}

// 删除照片
const deletePhoto = (id: string) => {
  const photo = capturedPhotos.value.find(p => p.id === id)
  if (photo) {
    URL.revokeObjectURL(photo.url)
  }
  capturedPhotos.value = capturedPhotos.value.filter(p => p.id !== id)
}

// 清空所有照片
const clearPhotos = () => {
  capturedPhotos.value.forEach(photo => {
    URL.revokeObjectURL(photo.url)
  })
  capturedPhotos.value = []
}

// 格式化文件大小
const formatFileSize = (bytes: number): string => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i]
}
</script>

